<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
<head>
  <link href="//gmpg.org/xfn/11" rel="profile">
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="generator" content="Hugo 0.68.3" />

  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>python三器 &middot; 我的博客</title>

  
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/print.css" media="print">
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/poole.css">
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/syntax.css">
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/hyde.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abril+Fatface|PT+Sans:400,400i,700">


  
  <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144-precomposed.png">
  <link rel="shortcut icon" href="/favicon.png">

  
  
</head>

  <body class="theme-base-0b ">
  <aside class="sidebar">
  <div class="container sidebar-sticky">
    <div class="sidebar-about">
      <a href="/my_technology_blog/"><h1>我的博客</h1></a>
      <p class="lead">
       杨博的博客 
      </p>
    </div>

    <nav>
      <ul class="sidebar-nav">
        <li><a href="/my_technology_blog/">Home</a> </li>
        
      </ul>
    </nav>

    <p>&copy; 2021. All rights reserved. </p>
  </div>
</aside>

    <main class="content container">
    <div class="post">
  <h1>python三器</h1>
  <time datetime=2020-06-26T13:55:39&#43;0800 class="post-date">Fri, Jun 26, 2020</time>
  <h2 id="装饰器">装饰器</h2>
<p><strong>1.</strong> <strong>装饰器定义</strong></p>
<p>​	在不修改源代码的基础上增加新的功能</p>
<p><strong>2.</strong> <strong>使用高阶函数模拟装饰器</strong></p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#75715e">#! /usr/bin/env python</span>
<span style="color:#75715e"># -*- coding: utf-8 -*-</span>
<span style="color:#f92672">import</span> time
<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">timer</span>(func):
    start_time <span style="color:#f92672">=</span> time<span style="color:#f92672">.</span>time()
    func()
    <span style="color:#66d9ef">print</span> <span style="color:#e6db74">&#39;函数执行时间为&#39;</span>, time<span style="color:#f92672">.</span>time() <span style="color:#f92672">-</span> start_time
<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">test</span>():
    <span style="color:#66d9ef">print</span> <span style="color:#e6db74">&#39;开始执行test&#39;</span>
    time<span style="color:#f92672">.</span>sleep(<span style="color:#ae81ff">3</span>)
    <span style="color:#66d9ef">print</span> <span style="color:#e6db74">&#39;test执行结束&#39;</span>
timer(test)
<span style="color:#e6db74">&#39;&#39;&#39;
</span><span style="color:#e6db74">开始执行test
</span><span style="color:#e6db74">test执行结束
</span><span style="color:#e6db74">函数执行时间为 3.00332999229
</span><span style="color:#e6db74">&#39;&#39;&#39;</span>
</code></pre></div><p><strong>3.</strong> <strong>计算运行时间装饰器</strong></p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#f92672">import</span> time
<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">timer</span>(func):   <span style="color:#75715e">#timer(test1)  func=test1</span>
    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">deco</span>(<span style="color:#f92672">*</span>args,<span style="color:#f92672">**</span>kwargs):
        start_time <span style="color:#f92672">=</span> time<span style="color:#f92672">.</span>time()
        func(<span style="color:#f92672">*</span>args,<span style="color:#f92672">**</span>kwargs)      <span style="color:#75715e">#run test1</span>
        stop_time <span style="color:#f92672">=</span> time<span style="color:#f92672">.</span>time()
        <span style="color:#66d9ef">print</span>(<span style="color:#e6db74">&#34;running time is </span><span style="color:#e6db74">%s</span><span style="color:#e6db74">&#34;</span><span style="color:#f92672">%</span>(stop_time<span style="color:#f92672">-</span>start_time))
    <span style="color:#66d9ef">return</span> deco
<span style="color:#a6e22e">@timer</span>     <span style="color:#75715e"># test1=timer(test1)</span>
<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">test1</span>():
    time<span style="color:#f92672">.</span>sleep(<span style="color:#ae81ff">3</span>)
    <span style="color:#66d9ef">print</span>(<span style="color:#e6db74">&#34;in the test1&#34;</span>)
test1()
</code></pre></div><p><strong>4. 装饰器使用场景</strong></p>
<p>授权：装饰器能有助于检查某个人是否被授权去使用一个web应用的端点(endpoint)。它们被大量使用于Flask和Django web框架中</p>
<p>日志：在记录日志的地方添加装饰器</p>
<p>缓存：通过装饰器获取缓存中的值</p>
<h2 id="生成器">生成器</h2>
<p><strong>1. 生成器定义</strong></p>
<p>生成器可以理解为一种数据类型，这种数据类型自动实现了迭代器协议（其他数据类型需要调用自己的内置iter方法）</p>
<p>在Python中，使用了 **yield ** 的函数被称为生成器</p>
<p>生成的是列表类型</p>
<p><strong>2、生成器的作用</strong></p>
<ol>
<li>
<p>通过列表生成式，我们可以直接创建一个列表，但是，受到内存限制，列表容量肯定是有限的。</p>
</li>
<li>
<p>而且，创建一个包含100万个元素的列表，不仅占用很大的存储空间，如果我们仅仅需要访问前面几个元素，那后面绝大多数元素占用的空间都白白浪费了。</p>
</li>
<li>
<p>所以，如果列表元素可以按照某种算法推算出来，那我们是否可以在循环的过程中不断推算出后续的元素呢？</p>
</li>
<li>
<p>这样就不必创建完整的list，从而节省大量的空间。在Python中，这种一边循环一边计算的机制，称为生成器：generator。</p>
</li>
</ol>
<p><strong>3. 生成器工作原理</strong></p>
<p>​	1）生成器是这样一个函数，它记住上一次返回时在函数体中的位置。</p>
<p>​	2）对生成器函数的第二次（或第 n 次）调用跳转至该函数中间，而上次调用的所有局部变量都保持不变。</p>
<p>​	3）生成器不仅“记住”了它数据状态；生成器还“记住”了它在流控制构造中的位置。</p>
<p>​	4）生成器是一个函数，而且函数的参数都会保留。</p>
<p>​	5）迭代到下一次的调用时，所使用的参数都是第一次所保留下的，即是说，在整个所有函数调用的参数都是第一次所调用时保留的，而不是新创建的</p>
<p><strong>4. yield</strong> <strong>生成器运行机制</strong></p>
<p>在Python中，yield就是这样的一个生成器。</p>
<p>​	1) 当你问生成器要一个数时，生成器会执行，直至出现<strong>yield</strong>语句，生成器把yield 的参数给你，之后生成器就不会往下继续运行。</p>
<p>​	2) 当你问他要下一个数时，他会从上次的状态开始运行，直至出现yield语句，把参数给你，之后停下。如此反复</p>
<p>​	3) 在python中，当你定义一个函数，使用了yield关键字时，这个函数就是一个生成器</p>
<p>​	4) 它的执行会和其他普通的函数有很多不同，函数返回的是一个对象，而不是你平常所用return语句那样，能得到结果值。如果想取得值，那得调用next()函数</p>
<p>​	5) 每当调用一次迭代器的next函数，生成器函数运行到yield之处，返回yield后面的值且在这个地方暂停，所有的状态都会被保持住，直到下次next函数被调用，或者碰到异常循环退出。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#75715e"># yield实现fib数</span>
<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">fib</span>(max_num):
    a,b <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">1</span>
    <span style="color:#66d9ef">while</span> a <span style="color:#f92672">&lt;</span> max_num:
        <span style="color:#66d9ef">yield</span> b
        a,b<span style="color:#f92672">=</span>b,a<span style="color:#f92672">+</span>b
 
g <span style="color:#f92672">=</span> fib(<span style="color:#ae81ff">10</span>)               <span style="color:#75715e">#生成一个生成器：[1，2, 3, 5, 8, 13]</span>
<span style="color:#66d9ef">print</span>(g<span style="color:#f92672">.</span>__next__())       <span style="color:#75715e">#第一次调用返回：1</span>
<span style="color:#66d9ef">print</span>(list(g))            <span style="color:#75715e">#把剩下元素变成列表：[2, 3, 5, 8, 13]</span>
</code></pre></div><h2 id="迭代器">迭代器</h2>
<p><strong>1.</strong> <strong>迭代器定义</strong></p>
<ol>
<li>
<p>迭代器是<strong>访问集合内元素</strong>的方式，迭代器对象从集合的第一个元素开始访问，直到所有的元素都被访问一遍后结束</p>
</li>
<li>
<p>迭代器仅是一容器对象，它有两个基本方法</p>
<p>1）**next()**方法：返回容器的下一个元素</p>
<p>2）<strong><strong>iter</strong></strong>()方法：返回迭代器自身</p>
</li>
</ol>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python">a <span style="color:#f92672">=</span> iter([<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">2</span>,])              <span style="color:#75715e">#生成一个迭代器</span>
<span style="color:#66d9ef">print</span>(a<span style="color:#f92672">.</span>__next__())
<span style="color:#66d9ef">print</span>(a<span style="color:#f92672">.</span>__next__())
<span style="color:#66d9ef">print</span>(a<span style="color:#f92672">.</span>__next__())           <span style="color:#75715e">#在这一步会引发  “StopIteration” 的异常</span>
</code></pre></div><p><strong>2.</strong> <strong>生成器和迭代器之间的区别</strong></p>
<p>​     在使用生成器时，我们创建一个函数；在使用迭代器时，我们使用内置函数iter()和next()。 在生成器中，我们使用关键字‘yield’来每次生成/返回一个对象。 生成器中有多少‘yield’语句，你可以自定义。 每次‘yield’暂停循环时，生成器会保存本地变量的状态。而迭代器并不会使用局部变量，它只需要一个可迭代对象进行迭代。 使用类可以实现你自己的迭代器，但无法实现生成器。 生成器运行速度快，语法简洁，更简单。 迭代器更能节约内存。</p>

</div>


    </main>

    
  </body>
</html>
